package com.anti.jdbc.support;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.lang.Nullable;

import javax.sql.DataSource;

/**
 * @Description 用于处理JdbcTemplate的连接操作，同时也定义Jdbc类型、初始化以及常用属性配置。
 * @Author anTi
 * @Date 2021-3-12
 */
public abstract class JdbcAccessor implements InitializingBean {
    /**
     *Setting Display SQL
     */
    private boolean showSQL=false;

    private String   interfaceClass;

    @Nullable
    private  DataSource dataSource;

    /**
     * 支持命名参数特性的特殊jdbcTemplate
     */
    private NamedParameterJdbcTemplate namedJdbcTemplate;
    /**
     * 对象锁
     */
    private static Object object=new Object();

    @Nullable
    private  JdbcTemplate jdbcTemplate;

    /**
     * 数据库类型
     */
    DataBaseType dataBaseType;

    private boolean lazyInit = true;

    public void setDataSource(@Nullable DataSource dataSource) {
        this.dataSource = dataSource;
        this.jdbcTemplate=new JdbcTemplate(dataSource);
    }

    @Nullable
    public DataSource getDataSource() {
        return this.dataSource;
    }

    @Nullable
    public JdbcTemplate getJdbcTemplate() {
        return jdbcTemplate;
    }

    public void setJdbcTemplate(@Nullable JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
        this.dataSource=jdbcTemplate.getDataSource();
    }

    public DataBaseType getDataBaseType() {
        return dataBaseType;
    }
    

    @Override
    public void afterPropertiesSet(){
        this.dataBaseType=checkDataBaseType(getDataSource());
    }

    public void setLazyInit(boolean lazyInit) {
        this.lazyInit = lazyInit;
    }

    public boolean isLazyInit() {
        return this.lazyInit;
    }


    DataBaseType checkDataBaseType(DataSource dataSource) {
        try {
            String driveClass = dataSource.getConnection().getMetaData().getDriverName().toLowerCase();
            if (driveClass.contains("mysql")) {
                return DataBaseType.MYSQL;
            } else {
                return driveClass.contains("oracle") ? DataBaseType.ORACLE : DataBaseType.UNKNOWN;
            }
        } catch (Exception exception) {
            exception.printStackTrace();
            return DataBaseType.UNKNOWN;
        }
    }

    public NamedParameterJdbcTemplate getNamedJdbcTemplate() {
        if (this.namedJdbcTemplate == null) {
            synchronized (object){
                if(this.namedJdbcTemplate==null){
                    this.namedJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
                }
            }
        }
        return this.namedJdbcTemplate;
    }

    public boolean isShowSQL() {
        return showSQL;
    }

    public void setShowSQL(boolean showSQL) {
        this.showSQL = showSQL;
    }

    public String getInterfaceClass() {
        this.interfaceClass=interfaceClass!=null?interfaceClass:"com.anti.jdbc.BaseJdbcTemplate";
        return interfaceClass;
    }
}
